package com.stitch.dcslock.aspect;

import com.stitch.dcslock.annotation.DistributedLock;
import com.stitch.dcslock.service.RedisLockService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁切面
 * - 在方法执行前加锁，执行后释放锁
 */
@Aspect
@Component
@Slf4j
public class DistributedLockAspect {
    private final RedisLockService lockService;

    public DistributedLockAspect(RedisLockService lockService) {
        this.lockService = lockService;
    }

    @Around("@annotation(lock)")
    public Object around(ProceedingJoinPoint joinPoint, DistributedLock lock) throws Throwable {
        String lockKey = lock.key();
        long waitTime = lock.waitTime();
        long leaseTime = lock.leaseTime();
        TimeUnit timeUnit = lock.timeUnit();

        if (lockService.tryLock(lockKey, waitTime, leaseTime, timeUnit)) {
            log.info("获取 Redis 锁成功: {}", lockKey);
            try {
                log.info("加锁成功，准备执行业务逻辑========》");
                return joinPoint.proceed(); // 执行原方法
            } finally {
                lockService.unlock(lockKey);
            }
        } else {
            log.warn("获取 Redis 锁失败: {}", lockKey);
            throw new RuntimeException("获取 Redis 锁失败");
        }
    }
}
